#include "QuoteMgr.h"

#include <core/Utility.h>
#include <string.h>

#include "CompanyReport.h"
#include "SSCompanyReportManager.h"

bool QuoteMgr::UpdateBondInfoByREPORT(CBondCompanyRep* pRep, REPORT* pReport,
                                      bool bVers, int bidask /*= 0*/) {
  // pReport从网络消息中解析而来
  Q_ASSERT(pReport);
  if (!pReport || !pRep) return false;

  REPORT report;
  memset(&report, 0, sizeof(report));

  if (strcmp(pReport->m_price_status, "0") == 0)  // 无效报价
  {
    if (bidask == 1) {
      if (strlen(pReport->m_bidinfo.m_sPrice) == 0)
        FIELDCOPY(pReport->m_bidinfo.m_sPrice, "Bid");
    }
    if (bidask == -1) {
      if (strlen(pReport->m_askinfo.m_sPrice) == 0)
        FIELDCOPY(pReport->m_askinfo.m_sPrice, "Ofr");
    }
  } else  // 有效报价
  {
    if (strcmp(pReport->m_bp_status, "0") !=
        0)  // 非0时，清空本地缓存数据。（0表示发布）
    {
      if (bidask == 1) {
        memset(pReport->m_bidinfo.m_quotetype, 0,
               sizeof(pReport->m_bidinfo.m_quotetype));
        memset(pReport->m_bidinfo.m_flag_bargain, 0,
               sizeof(pReport->m_bidinfo.m_flag_bargain));
        memset(pReport->m_bidinfo.m_flag_relation, 0,
               sizeof(pReport->m_bidinfo.m_flag_relation));
        memset(pReport->m_bidinfo.m_flag_vip, 0,
               sizeof(pReport->m_bidinfo.m_flag_vip));
        memset(pReport->m_bidinfo.m_flag_bad, 0,
               sizeof(pReport->m_bidinfo.m_flag_bad));
        memset(pReport->m_bidinfo.m_rebate, 0,
               sizeof(pReport->m_bidinfo.m_rebate));
        memset(pReport->m_bidinfo.m_description, 0,
               sizeof(pReport->m_bidinfo.m_description));
        memset(pReport->m_bidinfo.m_clean_price, 0,
               sizeof(pReport->m_bidinfo.m_clean_price));
        memset(pReport->m_bidinfo.m_sPrice, 0,
               sizeof(pReport->m_bidinfo.m_sPrice));
        memset(pReport->m_bidinfo.m_sVolume, 0,
               sizeof(pReport->m_bidinfo.m_sVolume));
        memset(pReport->m_bidinfo.m_yield_price, 0,
               sizeof(pReport->m_bidinfo.m_yield_price));
        memset(pReport->m_bidinfo.m_interpret, 0,
               sizeof(pReport->m_bidinfo.m_interpret));
      }
      if (bidask == -1) {
        memset(pReport->m_askinfo.m_quotetype, 0,
               sizeof(pReport->m_askinfo.m_quotetype));
        memset(pReport->m_askinfo.m_flag_bargain, 0,
               sizeof(pReport->m_askinfo.m_flag_bargain));
        memset(pReport->m_askinfo.m_flag_relation, 0,
               sizeof(pReport->m_askinfo.m_flag_relation));
        memset(pReport->m_askinfo.m_flag_vip, 0,
               sizeof(pReport->m_askinfo.m_flag_vip));
        memset(pReport->m_askinfo.m_flag_bad, 0,
               sizeof(pReport->m_askinfo.m_flag_bad));
        memset(pReport->m_askinfo.m_rebate, 0,
               sizeof(pReport->m_askinfo.m_rebate));
        memset(pReport->m_askinfo.m_description, 0,
               sizeof(pReport->m_askinfo.m_description));
        memset(pReport->m_askinfo.m_clean_price, 0,
               sizeof(pReport->m_askinfo.m_clean_price));
        memset(pReport->m_askinfo.m_sPrice, 0,
               sizeof(pReport->m_askinfo.m_sPrice));
        memset(pReport->m_askinfo.m_sVolume, 0,
               sizeof(pReport->m_askinfo.m_sVolume));
        memset(pReport->m_askinfo.m_yield_price, 0,
               sizeof(pReport->m_askinfo.m_yield_price));
        memset(pReport->m_askinfo.m_interpret, 0,
               sizeof(pReport->m_askinfo.m_interpret));
      }
    } else {
      if (bidask == 1) {
        if (strlen(pReport->m_bidinfo.m_sPrice) == 0) {
          memset(pReport->m_bidinfo.m_quotetype, 0,
                 sizeof(pReport->m_bidinfo.m_quotetype));
          FIELDCOPY(pReport->m_bidinfo.m_sPrice, "Bid");
        }
      }
      if (bidask == -1) {
        if (strlen(pReport->m_askinfo.m_sPrice) == 0) {
          memset(pReport->m_askinfo.m_quotetype, 0,
                 sizeof(pReport->m_askinfo.m_quotetype));
          FIELDCOPY(pReport->m_askinfo.m_sPrice, "Ofr");
        }
      }
    }
  }

  // if( strlen(pReport->m_szCode) > 0 )
  //	info.SetBondCode( pReport->m_szCode );

  bool bRet = pRep->GetCompanyRepByKey(pReport->m_company_id, report);
  if (bRet && bVers && report.m_dwVersion > pReport->m_dwVersion) {
    // TODO: LogReportErrorInfo(report, bidask, "m_dwVersion failed", pReport);
    return false;
  }

  if (bRet) {
    memset(report.m_bp_status, 0, sizeof(report.m_bp_status));
    memset(report.m_price_status, 0, sizeof(report.m_price_status));

    FIELDCOPY(report.m_bp_status, pReport->m_bp_status);
    FIELDCOPY(report.m_price_status, pReport->m_price_status);
    if (bidask == 1 &&
        (report.m_bidinfo.m_create_time <= pReport->m_bidinfo.m_create_time ||
         report.m_bidinfo.m_time <= pReport->m_bidinfo.m_time)) {
      memset(&report.m_bidinfo, 0, sizeof(PRICE));
      report.m_bidinfo = pReport->m_bidinfo;
      if (pReport->m_company_id[0] != 'e' ||
          (pReport->m_company_id[0] == 'e' &&
           pReport->m_tradePrice[0] != '\0')) {
        // 交易所行情，如果成交为空，则不覆盖本地缓存
        FIELDCOPY(report.m_tradePrice, pReport->m_tradePrice);
      }
    } else if (bidask == -1 &&
               (report.m_askinfo.m_create_time <=
                    pReport->m_askinfo.m_create_time ||
                report.m_askinfo.m_time <= pReport->m_askinfo.m_time)) {
      memset(&report.m_askinfo, 0, sizeof(PRICE));
      report.m_askinfo = pReport->m_askinfo;
      if (pReport->m_company_id[0] != 'e' ||
          (pReport->m_company_id[0] == 'e' &&
           pReport->m_tradePrice[0] != '\0')) {
        // 交易所行情，如果成交为空，则不覆盖本地缓存
        FIELDCOPY(report.m_tradePrice, pReport->m_tradePrice);
      }
    } else if (bidask == 0 && report.m_indx_info.m_modify_time <=
                                  pReport->m_indx_info.m_modify_time) {
      report.m_indx_info = pReport->m_indx_info;  // 参考价
    } else {
      // LogReportErrorInfo(report, bidask, "modifytime is old", pReport);
      return false;
    }

    report.m_create_time = max(pReport->m_time, pReport->m_create_time);
    report.m_time = max(pReport->m_time, pReport->m_create_time);
    report.m_dwVersion = pReport->m_dwVersion;

    report.m_pkg_id = pReport->m_pkg_id;
    pRep->InsertCompanyRep(report);

    // LogReportInfo(report, bidask, "Storaged", NULL);
  } else {
    pRep->InsertCompanyRep(*pReport);
    // LogReportInfo(report, bidask, "CompanyRep not find", NULL);
  }

  return true;
}

bool QuoteMgr::UpdateBondContainerByREPORT(
    CBondContainer& container, REPORT* pReport, bool bAddIfNotExist, bool bVers,
    REPORT* pReportLast /*= nullptr*/, int bidask /*= 0*/, int local /*= 0*/) {
  // pReport 从消息中解析而来
  Q_ASSERT(pReport);
  if (nullptr == pReport) return false;

  int id = 0;
  if (!container.GetBondInfoByKey(pReport->m_sBondKey, pReport->m_sListedMarket,
                                  nullptr, &id))
    return true;

  CBondCompanyRep* prep = BrokerRepMng->GetReportOrAdd(id);
  if (prep) {
    if (UpdateBondInfoByREPORT(prep, pReport, bVers, bidask)) {
      int nVer = container.GetVersionById(pReport->m_company_id);
      if (nVer < (int)pReport->m_dwVersion) {
        container.UpdateVersionById(pReport->m_company_id, pReport->m_dwVersion,
                                    pReport->m_create_time);
      }
    }
  }

  return true;
}
